00001 // Emacs Mode Line: -*- Mode:c++;-*- 00002 // ------------------------------------------------------------- 00003 /* 00004 * Copyright (c) 2013 Battelle Memorial Institute 00005 * Licensed under modified BSD License. A copy of this license can be found 00006 * in the LICENSE file in the top level directory of this distribution. 00007 */ 00008 // ------------------------------------------------------------- 00009 // ------------------------------------------------------------- 00010 /** 00011 * @file matrix_interface.hpp 00012 * @author William A. Perkins 00013 * @date 2015-06-09 15:06:46 d3g096 00014 * 00015 * @brief Declaration of the abstract BaseMatrixInterface template class. 00016 * 00017 * 00018 */ 00019 // ------------------------------------------------------------- 00020 // ------------------------------------------------------------- 00021 // Created October 21, 2014 by William A. Perkins 00022 // Last Change: 2013-05-03 12:23:12 d3g096 00023 // ------------------------------------------------------------- 00024 00025 #ifndef _matrix_interface_hpp_ 00026 #define _matrix_interface_hpp_ 00027 00028 #include "gridpack/math/implementation_visitable.hpp" 00029 00030 namespace gridpack { 00031 namespace math { 00032 00033 // ------------------------------------------------------------- 00034 // class BaseMatrixInterface 00035 // ------------------------------------------------------------- 00036 /// Abstract interface for matrix classes 00037 template<typename T, typename I = int> 00038 class BaseMatrixInterface 00039 : public ImplementationVisitable 00040 { 00041 public: 00042 00043 typedef T TheType; /**< The numeric type used. */ 00044 typedef I IdxType; /**< The size/index type used. */ 00045 00046 /// Default constructor. 00047 BaseMatrixInterface(void) 00048 : ImplementationVisitable() 00049 {} 00050 00051 /// Destructor 00052 ~BaseMatrixInterface(void) 00053 {} 00054 00055 /// Get the global index range of the locally owned rows 00056 /** 00057 * @e Local. 00058 * 00059 * 00060 * 00061 * @param lo first (0-based) index of locally owned rows 00062 * @param hi one more than the last (0-based) index of locally owned rows 00063 */ 00064 void localRowRange(IdxType& lo, IdxType& hi) const 00065 { 00066 this->p_localRowRange(lo, hi); 00067 } 00068 00069 /// Get the total number of rows in this matrix 00070 /** 00071 * @e Local. 00072 * 00073 * 00074 * @return total number of rows 00075 */ 00076 IdxType rows(void) const 00077 { 00078 return this->p_rows(); 00079 } 00080 00081 /// Get the number of local rows in this matirx 00082 IdxType localRows(void) const 00083 /** 00084 * @e Local. 00085 * 00086 * 00087 * @return number of rows owned by this process 00088 */ 00089 { 00090 return this->p_localRows(); 00091 } 00092 00093 /// Get the number of columns in this matrix 00094 /** 00095 * @e Local. 00096 * 00097 * 00098 * @return number of columns in matrix 00099 */ 00100 IdxType cols(void) const 00101 { 00102 return this->p_cols(); 00103 } 00104 00105 /// Get the number of local columns in this matirx 00106 IdxType localCols(void) const 00107 { 00108 return this->p_localCols(); 00109 } 00110 00111 /// Set an individual element 00112 /** 00113 * @e Local. 00114 * 00115 * This overwrites the value at the specified @c i row and @c j 00116 * column. ready() must be called after all setElement() calls and 00117 * before using the matrix. 00118 * 00119 * @param i global (0-based) row index 00120 * @param j global (0-based) column index 00121 * @param x value to place in matrix 00122 */ 00123 void setElement(const IdxType& i, const IdxType& j, const TheType& x) 00124 { 00125 this->p_setElement(i, j, x); 00126 } 00127 00128 /// Set an several elements 00129 /** 00130 * @e Local. 00131 * 00132 * This overwrites values at several locations in the 00133 * matrix. ready() must be called after all setElements() calls and 00134 * before using the matrix. 00135 * 00136 * @param n number of values to place in 00137 * @param i array of @c n global, 0-based row indexes 00138 * @param j array of @c n global, 0-based column indexes 00139 * @param x array of @c n values to replace existing matrix elements 00140 */ 00141 void setElements(const IdxType& n, const IdxType *i, const IdxType *j, const TheType *x) 00142 { 00143 this->p_setElements(n, i, j, x); 00144 } 00145 00146 /// Add to an individual element 00147 /** 00148 * @e Local. 00149 * 00150 * 00151 * @param i global, 0-based row index 00152 * @param j global, 0-based column index 00153 * @param x value to add to matrix element 00154 */ 00155 void addElement(const IdxType& i, const IdxType& j, const TheType& x) 00156 { 00157 this->p_addElement(i, j, x); 00158 } 00159 00160 /// Add to an several elements 00161 /** 00162 * @e Local. 00163 * 00164 * @param n number of elements to update 00165 * @param i array of @c n global, 0-based row indexes 00166 * @param j array of @c n global, 0-based column indexes 00167 * @param x array of @c n values to add to existing matrix elements 00168 */ 00169 void addElements(const IdxType& n, const IdxType *i, const IdxType *j, const TheType *x) 00170 { 00171 this->p_addElements(n, i, j, x); 00172 } 00173 00174 /// Get an individual element 00175 /** 00176 * @c Local. 00177 * 00178 * Only local elements may be retrieved using this method. 00179 * 00180 * @param i global, 0-based row index 00181 * @param j global, 0-based column index 00182 * @param x variable in which to place retrieved value 00183 */ 00184 void getElement(const IdxType& i, const IdxType& j, TheType& x) const 00185 { 00186 this->p_getElement(i, j, x); 00187 } 00188 00189 /// Get an several elements 00190 /** 00191 * @c Local. 00192 * 00193 * Only local elements may be retrieved using this method. 00194 * 00195 * @param n number of elements to retrieve 00196 * @param i array of @c n global, 0-based row indexes 00197 * @param j array of @c n global, 0-based column indexes 00198 * @param x array of @c n values in which retrieved values are to be placed 00199 */ 00200 void getElements(const IdxType& n, const IdxType *i, const IdxType *j, TheType *x) const 00201 { 00202 this->p_getElements(n, i, j, x); 00203 } 00204 00205 /// Get a row and put it in a local array 00206 void getRow(const IdxType& row, TheType *x) const 00207 { 00208 this->p_getRow(row, x); 00209 } 00210 00211 /// Get some rows and put them in a local array 00212 /** 00213 * (Collective) 00214 * 00215 * This gets the elements in the specified rows and puts them in the 00216 * specified array. It is assumed that the array is appropriately 00217 * sized (nrow * columns). While this is collective, each processor 00218 * may get a different set of rows. Row/column ownership should not 00219 * matter. 00220 * 00221 * @param nrow 00222 * @param rows 00223 * @param x 00224 */ 00225 void getRowBlock(const IdxType& nrow, const IdxType *rows, TheType *x) const 00226 { 00227 this->p_getRowBlock(nrow, rows, x); 00228 } 00229 00230 00231 /// Make this matrix the identity matrix 00232 /** 00233 * @e Collective 00234 * 00235 * 00236 * 00237 */ 00238 void identity(void) 00239 { 00240 this->p_identity(); 00241 } 00242 00243 /// Shift the diagonal of this matrix by the specified value 00244 /** 00245 * @c Collective. 00246 * 00247 * @param x 00248 */ 00249 void addDiagonal(const TheType& x) 00250 { 00251 this->p_addDiagonal(x); 00252 } 00253 00254 /// Scale this entire MatrixT by the given value 00255 /** 00256 * @e Collective. 00257 * 00258 * @param x factor by which all elements in the matrix are multiplied 00259 */ 00260 void scale(const TheType& x) 00261 { 00262 this->p_scale(x); 00263 } 00264 00265 /// Replace all elements with their real parts 00266 void real(void) 00267 { 00268 this->p_real(); 00269 } 00270 00271 /// Replace all elements with their imaginary parts 00272 void imaginary(void) 00273 { 00274 this->p_imaginary(); 00275 } 00276 00277 /// Replace all elements with their complex gradient 00278 void conjugate(void) 00279 { 00280 this->p_conjugate(); 00281 } 00282 00283 /// Compute the matrix L<sup>2</sup> norm 00284 /** 00285 * @e Collective. 00286 * 00287 * The vector L<sup>2</sup>, or Euclidian, norm is computed as 00288 * \f[ 00289 * \left\| \mathbf{A} \right\| ~ = ~ \sqrt{\sum_{ij} A_{ij}^{2}} 00290 * \f] 00291 * 00292 * @return L<sup>2</sup> norm of this matrix 00293 */ 00294 double norm2(void) const 00295 { 00296 return this->p_norm2(); 00297 } 00298 00299 /// Zero all entries in the matrix 00300 /** 00301 * @e Collective. 00302 * 00303 */ 00304 void zero(void) 00305 { 00306 this->p_zero(); 00307 } 00308 00309 /// Indicate the matrix is ready to use 00310 /** 00311 * @e Collective. 00312 * 00313 * This is used to indicate that the matrix is ready to use. This 00314 * must be called after @e all setElement() or addElement() calls 00315 * and before the vector is used for any operation. 00316 */ 00317 void ready(void) 00318 { 00319 this->p_ready(); 00320 } 00321 00322 /// Print to named file or standard output 00323 /** 00324 * @e Collective. 00325 * 00326 * 00327 * 00328 * The format is dependent on the specific vector implementation. 00329 * 00330 * @param filename optional file 00331 */ 00332 void print(const char* filename = NULL) const 00333 { 00334 this->p_print(filename); 00335 } 00336 00337 /// Save, in MatLAB format, to named file (collective) 00338 /** 00339 * @e Collective. 00340 * 00341 * 00342 * 00343 * @param filename 00344 */ 00345 void save(const char *filename) const 00346 { 00347 this->p_save(filename); 00348 } 00349 00350 /// Load from a named file of whatever binary format the math library uses 00351 /** 00352 * @e Collective. 00353 * 00354 * The underlying math library generally supports some way to save a 00355 * matrix to a file. This will load elements from a file of that 00356 * format. 00357 * 00358 * @param filename 00359 */ 00360 void loadBinary(const char *filename) 00361 { 00362 this->p_loadBinary(filename); 00363 } 00364 00365 00366 /// Save to named file in whatever binary format the math library uses 00367 /** 00368 * @e Collective. 00369 * 00370 * The underlying math library generally supports some way to save a 00371 * matrix to a file. This routine uses whatever format that can be 00372 * read by ::loadBinary(). 00373 * 00374 * @param filename 00375 */ 00376 void saveBinary(const char *filename) const 00377 { 00378 this->p_saveBinary(filename); 00379 } 00380 00381 protected: 00382 00383 /// Get the global index range of the locally owned rows (specialized) 00384 virtual void p_localRowRange(IdxType& lo, IdxType& hi) const = 0; 00385 00386 /// Get the total number of rows in this matrix (specialized) 00387 virtual IdxType p_rows(void) const = 0; 00388 00389 /// Get the number of local rows in this matirx (specialized) 00390 virtual IdxType p_localRows(void) const = 0; 00391 00392 /// Get the number of columns in this matrix (specialized) 00393 virtual IdxType p_cols(void) const = 0; 00394 00395 /// Get the number of local rows in this matirx (specialized) 00396 virtual IdxType p_localCols(void) const = 0; 00397 00398 /// Set an individual element (specialized) 00399 virtual void p_setElement(const IdxType& i, const IdxType& j, const TheType& x) = 0; 00400 00401 /// Set an several element (specialized) 00402 virtual void p_setElements(const IdxType& n, const IdxType *i, const IdxType *j, 00403 const TheType *x) = 0; 00404 00405 /// Add to an individual element (specialized) 00406 virtual void p_addElement(const IdxType& i, const IdxType& j, const TheType& x) = 0; 00407 00408 /// Add to an several element (specialized) 00409 virtual void p_addElements(const IdxType& n, const IdxType *i, const IdxType *j, 00410 const TheType *x) = 0; 00411 00412 /// Get an individual element (specialized) 00413 virtual void p_getElement(const IdxType& i, const IdxType& j, TheType& x) const = 0; 00414 00415 /// Get an several element (specialized) 00416 virtual void p_getElements(const IdxType& n, const IdxType *i, const IdxType *j, 00417 TheType *x) const = 0; 00418 00419 /// Shift the diagonal of this matrix by the specified value (specialized) 00420 virtual void p_addDiagonal(const TheType& x) = 0; 00421 00422 /// Make this matrix the identity matrix (specialized) 00423 virtual void p_identity(void) = 0; 00424 00425 /// Scale this entire MatrixT by the given value (specialized) 00426 virtual void p_scale(const TheType& x) = 0; 00427 00428 /// Get a row and put it in a local array (specialized) 00429 virtual void p_getRow(const IdxType& row, TheType *x) const 00430 { 00431 p_getRowBlock(1, &row, x); 00432 } 00433 00434 /// Get some rows and put them in a local array (specialized) 00435 virtual void p_getRowBlock(const IdxType& nrow, const IdxType *rows, TheType *x) const = 0; 00436 00437 00438 /// Replace all elements with their real parts (specialized) 00439 virtual void p_real(void) = 0; 00440 00441 /// Replace all elements with their imaginary parts (specialized) 00442 virtual void p_imaginary(void) = 0; 00443 00444 /// Replace all elements with their complex gradient (specialized) 00445 virtual void p_conjugate(void) = 0; 00446 00447 /// Compute the matrix L<sup>2</sup> norm (specialized) 00448 virtual double p_norm2(void) const = 0; 00449 00450 /// Zero all entries in the matrix (specialized) 00451 virtual void p_zero(void) = 0; 00452 00453 /// Make this instance ready to use 00454 virtual void p_ready(void) = 0; 00455 00456 /// Print to named file or standard output 00457 virtual void p_print(const char* filename = NULL) const = 0; 00458 00459 /// Save, in MatLAB format, to named file (collective) 00460 virtual void p_save(const char *filename) const = 0; 00461 00462 /// Load from a named file of whatever binary format the math library uses 00463 virtual void p_loadBinary(const char *filename) = 0; 00464 00465 /// Save to named file in whatever binary format the math library uses 00466 virtual void p_saveBinary(const char *filename) const = 0; 00467 }; 00468 00469 00470 } // namespace math 00471 } // namespace gridpack 00472 00473 #endif